package dataguide;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Stack;

/*** @author Nicoleta Preda (andapreda@gmail.com) */
public class Node implements Comparable{

	public static final int ATT=0;
	public static final int ELEM=1;
	public static final int VALUE=2;
	public static final int DG_ROOT=3;
	public static int counter=1;
	
	public String name; 
	public HashSet<String> inputCalls=null;
	public int kid;		
	public int type=ELEM;
	public Node parent=null;
	public HashMap<String, Node> sons;

  /*******************************************/
	
  public Node(String name, int type, Node parent)
  {
  	this.name=name;
	this.kid=counter++;	
  	this.sons= new HashMap<String, Node>();
  	inputCalls=new HashSet<String>();
  	this.type=type;
  	this.parent=parent;
  } 

	
  /*******************************************/
	
	public boolean equals(Object node)
	{
		if(name==null) return false;
		if(!  (node instanceof Node)) return false;
		
		Node n =(Node)node;		
		if(!name.equals(n.name)) return false;
		return n.kid==kid;
	}	
	
	public int hashCode()
	{return (name+kid).hashCode();}
	
	public int compareTo(Object o)
	{
		if( !(o instanceof Node)) return -2;
		Node n=(Node)o;
		if(kid<n.KID()) return -1;
		if(kid>n.KID()) return 1;		
		if(name==null) return -1;
		return  name.compareToIgnoreCase(n.name());
	}
	/***********************************/
	
	public ArrayList<Node> getPathRootToNode(){
		Node p=parent;
		ArrayList<Node> list= new ArrayList<Node>();
		while (p!=null)
		{
			list.add(0, p);
			p=p.parent;
		}
		list.add(this);
		/** remove the artificial root that we have added */
		list.remove(0);
		return list;
	}
	
	
	
	/***********************************/
	public String toString()
	{
		
		Node p=parent;
		ArrayList<Node> list= new ArrayList<Node>();
		while (p!=null)
		{
			list.add(0, p);
			p=p.parent;
		}
		list.add(this);
		
		StringBuffer b= new StringBuffer();
		b.append("Path=");
		for(Node n: list){
			b.append(n.name+"/");
		}
		b.append("\nValues={\n\t");
		for(Node n: sons.values()){
			b.append(n.name+"\n\t");
		}
		b.append("}");
		
		return b.toString();
	}

  	/***********************************/
  	
  	public String name()
  	{
  		return name;
  	}
  	
  	public int KID()
  	{
  		return kid;
  	}
 
  	/***********************************/
  	
  	public Node getOrCreate(String name, int type){
  		Node n=sons.get(name);
  		if(n==null) {
  			n=new Node(name,type,this);
  			sons.put(name, n);
  			n.parent=this;
  			} 
  		return n;
  	}
	
}
